package com.systar.activity.parse;

import java.io.BufferedReader;
import java.nio.CharBuffer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.google.common.eventbus.EventBus;
import com.systar.activity.state.FileActivity;

public class SessionFileParserRegExp extends SessionFileParser
{
	private static final int DEFAULT_MAX_READ_SIZE = 1000000;
	private static final int DEFAULT_MAX_RETENTION_SIZE = 255;

	private int MAX_READ_SIZE = DEFAULT_MAX_READ_SIZE;
	private int MAX_RETENTION_SIZE = DEFAULT_MAX_RETENTION_SIZE;

	public SessionFileParserRegExp(FileActivity activity, EventBus eventBus)
	{
		super(activity, eventBus);
	}

	public void setBuffers(int readSize, int retentionSize)
	{
		MAX_READ_SIZE = readSize;
		MAX_RETENTION_SIZE = retentionSize;
	}

	@Override
	public Integer call() throws Exception
	{
		nbInfo = nbWarn = nbErr = 0;

		try
		{
			Pattern messagePattern = Pattern.compile(
					"<event\\s.*\\skind=\"((?:\\p{Alpha})+).*\\n.*\\spriority=\"((?:\\p{Alpha})+).*\\n.*<message>((?:\\p{Print})+)</message>",
					Pattern.MULTILINE);
			int bufferSize = MAX_READ_SIZE + MAX_RETENTION_SIZE;
			char[] buffer = new char[bufferSize];

			BufferedReader reader = activity.getReader();
			int readSize = reader.read(buffer, 0, MAX_READ_SIZE);
			int scanSize = readSize;
			while (readSize > 0)
			{
				int position = 0;
				Matcher messageMatcher = messagePattern.matcher(CharBuffer.wrap(buffer, 0, scanSize));
				while (messageMatcher.find())
				{
					String kind = messageMatcher.group(1);
					String priority = messageMatcher.group(2);
					String message = messageMatcher.group(3);

					submit(kind, priority, message);

					position = messageMatcher.end(3);
				}
				// to avoid lost messages because buffer split the message in 2, we keep a retention block 
				int retentionSize = Math.min(scanSize - position, MAX_RETENTION_SIZE);
				if (retentionSize > 0)
				{
					// copy retention at beginning of buffer
					System.arraycopy(buffer, scanSize - retentionSize, buffer, 0, retentionSize);
				}
				readSize = reader.read(buffer, retentionSize, MAX_READ_SIZE);
				scanSize = readSize + retentionSize;
			}
			flush();
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		return 0;
	}

}
